package com.projectxxxxxxxxxx.utils;

import java.util.Timer;
import java.util.TimerTask;

public interface ScheduledTask {

	void cancel();

	long currentTimeMillis();

	void schedule(TimerTask task, long delay);

	void scheduleAtFixedRate(TimerTask task, long delay);

	public class DefaultScheduledTask implements ScheduledTask {
		private boolean hasPending;
		private final Timer timer;

		public DefaultScheduledTask() {
			timer = new Timer();
			hasPending = false;
		}

		@Override
		public synchronized void cancel() {
			timer.cancel();
		}

		@Override
		public long currentTimeMillis() {
			return System.currentTimeMillis();
		}

		private boolean hasPending() {
			return hasPending;
		}

		private void setPending(boolean hasPending) {
			this.hasPending = hasPending;
		}

		@Override
		public synchronized void schedule(TimerTask task, long delay) {
			if (hasPending()) {
				return;
			}
			setPending(true);
			timer.schedule(new TimerTaskScheduled(task), delay);
		}

		@Override
		public synchronized void scheduleAtFixedRate(TimerTask task, long delay) {
			if (hasPending()) {
				return;
			}
			setPending(true);
			timer.scheduleAtFixedRate(new TimerTaskScheduled(task), 0L, delay);
		}

		final class TimerTaskScheduled extends TimerTask {
			TimerTask task;

			public TimerTaskScheduled(TimerTask task) {
				this.task = task;
			}

			@Override
			public void run() {
				setPending(false);
				task.run();
			}
		}
	}
}
